package genedit.view.graph;

import genedit.gui.exceptions.ElementNePostoji;
import genedit.model.graph.GraphElement;
import genedit.model.graph.Property;
import genedit.model.graph.classModel.GAttribute;
import genedit.model.graph.classModel.GAttributes;
import genedit.model.graph.classModel.GMethod;
import genedit.model.graph.classModel.GMethods;
import genedit.model.graph.classModel.InterfaceModel;

import java.awt.Color;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.GradientPaint;
import java.awt.Graphics2D;
import java.awt.Paint;
import java.awt.Rectangle;
import java.awt.Shape;
import java.awt.Stroke;
import java.awt.geom.AffineTransform;
import java.awt.geom.Rectangle2D;
import java.util.ArrayList;
import java.util.Iterator;

public class InterfaceModelPainter extends ClassModelPainter {

	public InterfaceModelPainter(GraphElement element) {
		super(element);
		transform = new AffineTransform();
		
		shape = new java.awt.geom.Rectangle2D.Double(0, 0, element.getSize()
				.getWidth(), element.getSize().getHeight());
	}
	
	@Override
	public void paint(Graphics2D g) {
		
		InterfaceModel element=(InterfaceModel)getElement();
		
		Color backupColor=g.getColor();
		g.setColor(element.getColor());
		Stroke backupStroke = g.getStroke();
		g.setStroke(element.getStroke());
		Paint backupPaint = g.getPaint();
		
		AffineTransform backupTransformation=g.getTransform();
		refreshAffine();
		g.transform(transform);
		
		Shape interfaceShape = new Rectangle(0,0,(int) element.getSize().getWidth(),(int) element.getSize().getHeight());
		Paint fill = new GradientPaint(0, 0, Color.MAGENTA, (int) element.getSize().getWidth(), (int) element.getSize().getHeight(), Color.WHITE);
		g.setPaint(fill);
	    g.fill(interfaceShape);
	    g.setPaint(backupPaint);
	    
		Shape backupClip = g.getClip();
		g.draw(shape);
		
		//iscrtaj dve linije
		Rectangle2D baseShapeRect=shape.getBounds2D();
		g.drawLine(0,(int) (baseShapeRect.getHeight()/3),(int) (baseShapeRect.getWidth()), (int) (baseShapeRect.getHeight()/3));
		g.drawLine(0,(int) (2*baseShapeRect.getHeight()/3),(int) (baseShapeRect.getWidth()), (int) (2*baseShapeRect.getHeight()/3));
		
		// iscrtavanje imena InterfaceModel-a
		Rectangle clipName = new Rectangle(0,0,(int)element.getSize().getWidth(),(int)(element.getSize().getHeight()/3));
		g.setPaint(Color.BLACK);
		g.setFont(new Font("Arial",Font.BOLD,9));
		FontMetrics fm = g.getFontMetrics(g.getFont());
		Rectangle2D rectangle = fm.getStringBounds(element.getName(), g);
	    textHeightGlobal = (int)(rectangle.getHeight());
	    g.clipRect(clipName.x, clipName.y, clipName.width, clipName.height);
	    drawCenteredStringConcrete(g,"<<interface>>",0,0,(int)element.getSize().getWidth(),(int)element.getSize().getHeight(), 0);
		drawCenteredStringConcrete(g,element.getName(),0,textHeightGlobal,(int)element.getSize().getWidth(),(int)element.getSize().getHeight(), 1);
		
		// iscrtavanje atributa InterfaceModel-a
		g.setClip(backupClip);
		Rectangle clipAtributes = new Rectangle(0,(int)(element.getSize().getHeight()/3),(int)element.getSize().getWidth(),(int)(element.getSize().getHeight()/3));
		g.setPaint(Color.BLACK);
		g.setFont(new Font("Arial",Font.BOLD,9));
		g.clipRect(clipAtributes.x, clipAtributes.y, clipAtributes.width, clipAtributes.height);
		
		Iterator<Property> it = element.getIteratorProperties();
		Property attributes = null;
		Property methods = null;
		while(it.hasNext()) {
			Property temp = it.next();
			if(temp.getKey().equals("attributes")) {
				
				attributes = temp;
				
			} else if (temp.getKey().equals("methods")) {
				
				methods = temp;
			}
		}
		
		GAttributes attribute = (GAttributes)attributes.getValue();
		GMethods method = (GMethods)methods.getValue();
		
		ArrayList<GAttribute> at = new ArrayList<GAttribute>();
		ArrayList<GMethod> met = new ArrayList<GMethod>();
		
		Iterator<String> itAtt = attribute.getAtributeIterator();
		
		while(itAtt.hasNext()) {
			String att = itAtt.next();
			try {
				at.add(attribute.getAtribute(att));
			} catch (ElementNePostoji e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		at.addAll(attribute.getInheritedAttributes().values());
		
		for(int i = 0; i < at.size(); ++i) {
			drawCenteredStringConcrete(g,(at.get(i)).toString(),0,(int)(i*textHeightGlobal + element.getSize().getHeight()/3),(int)element.getSize().getWidth(),(int)(element.getSize().getHeight()/3), i);
		}
		
		// iscrtavanje metoda InterfaceModel-a
		g.setClip(backupClip);
		Rectangle clipMethods = new Rectangle(0,(int)(2*element.getSize().getHeight()/3),(int)element.getSize().getWidth(),(int)(element.getSize().getHeight()/3));
		g.setPaint(Color.BLACK);
		g.setFont(new Font("Arial",Font.BOLD,9));
		g.clipRect(clipMethods.x, clipMethods.y, clipMethods.width, clipMethods.height);

		Iterator<String> itMth = method.getMethodIterator();
		
		while(itMth.hasNext()) {
			String mth = itMth.next();
			try {
				met.add(method.getMethod(mth));
			} catch (ElementNePostoji e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		met.addAll(method.getInheritedMethods());
		
		for(int i = 0; i < met.size(); ++i) {
		    drawCenteredStringConcrete(g,(met.get(i)).toString(),0,(int)(i*textHeightGlobal + 2*element.getSize().getHeight()/3),(int)element.getSize().getWidth(),(int)(element.getSize().getHeight()/3), i);
		}
	
		g.setClip(backupClip);
		g.setTransform(backupTransformation);
		g.setStroke(backupStroke);
		g.setColor(backupColor);
		g.setPaint(backupPaint);
	}

}
